package com.huitone.gddw.service.impl.worktable;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.huitone.gddw.common.ComConstant;
import com.huitone.gddw.dao.entity.BlackUse;
import com.huitone.gddw.dao.entity.ErrorMng;
import com.huitone.gddw.dao.entity.InputLine;
import com.huitone.gddw.dao.entity.InvalidUse;
import com.huitone.gddw.dao.entity.RedUserList;
import com.huitone.gddw.dao.entity.UploadFile;
import com.huitone.gddw.dao.entity.WebSmRec;
import com.huitone.gddw.dao.worktable.paramconfigmanage.IUploadFileDao;
import com.huitone.gddw.model.support.QueryPage;
import com.huitone.gddw.service.IBlackUseService;
import com.huitone.gddw.service.IErrorMngService;
import com.huitone.gddw.service.IInputLineService;
import com.huitone.gddw.service.IInvalidUseService;
import com.huitone.gddw.service.IRedUserListService;
import com.huitone.gddw.service.IUploadFileService;
import com.huitone.gddw.service.business.IWebSmRecService;
import com.huitone.gddw.service.dto.UploadFileDTO;
import com.huitone.gddw.service.dto.business.UploadWebSmDTO;
import com.huitone.gddw.service.system.IRoleService;
import com.huitone.gddw.utils.SysLoginUtil;

/**
 * 文件上传记录 接口实现类
 * @author wuluodan
 *
 */
@Service
public class UploadFileService implements IUploadFileService {

	private static final Integer NUMBER_1 = 1;
	private static final Integer NUMBER_2 = 2;
	private static final Integer NUMBER_5 = 5;
	
	private static final String FORMAT_ERROR = "格式不正确";
	private static final String INPUT_ERROR = "导入失败";
	private static final String AUDIT_STATUS_UN = "0"; 		// 待审核
	private static final String AUDIT_STATUS_PASS = "1"; 	// 审核通过
	private static final String AUDIT_STATUS_NON = "2"; 	// 审核不通过
	private static final String STATUS_INVALID = "0"; 		// 无效
	private static final String STATUS_VALID = "1"; 		// 有效
	private static final String STATUS_FAIL = "0"; 			// 失败
	private static final String STATUS_SUCCESS = "1"; 		// 成功
	
	@Autowired
	private IUploadFileDao uploadFileDao;
	
	@Autowired
	private IErrorMngService errorMngService;
	
	@Autowired
	private IBlackUseService blackUseService;
	
	@Autowired
	private IRedUserListService redUseService;
	
	@Autowired
	private IInvalidUseService invalidUseService;
	
	@Autowired
	private IInputLineService inputLineService;
	
	@Autowired
	private IWebSmRecService webSmRecService;
	
	@Autowired
	private IRoleService roleService;
	
	@Override
	public QueryPage<?> selectPage(QueryPage<?> page) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("fileName", page.getParams().get("fileName"));
		map.put("userName", page.getParams().get("userName"));
		map.put("auditStatus", page.getParams().get("auditStatus"));
		map.put("startDate", page.getParams().get("startDate"));
		map.put("endDate", page.getParams().get("endDate"));
		map.put("blackUser", page.getParams().get("blackUser"));
		map.put("invalidUser", page.getParams().get("invalidUser"));
		map.put("start", (page.getPageNo() - 1) * page.getPageSize() + 1);
		map.put("end", page.getPageNo() * page.getPageSize());
		map.put("userId", SysLoginUtil.getLoginUserId());
		map.put("fileType", page.getParams().get("fileType"));
		
		if (page.getParams().get("fileType") != null && !"".equals(page.getParams().get("fileType").toString())) {
			if (page.getParams().get("fileType").equals(ComConstant.SMS_PHONE)) {
				map.put("svrNode", page.getParams().get("svrNode"));
				map.put("serviceCode", page.getParams().get("serviceCode"));
				
				List<UploadWebSmDTO> result = null;
				int totalCount = 0;
				if (roleService.isRootAcsFlag(SysLoginUtil.getLoginUserId())) {
					result = webSmRecService.selectRoot(map);
					totalCount = webSmRecService.countRoot(map);
				} else {
					result = webSmRecService.selectUnit(map);
					totalCount = webSmRecService.countUnit(map);
				}
				
				QueryPage<UploadWebSmDTO> queryPage = new QueryPage<UploadWebSmDTO>();
				queryPage.setResult(result);
				queryPage.setPageNo(page.getPageNo());
				queryPage.setPageSize(page.getPageSize());
				queryPage.setTotalCount(totalCount);
				return queryPage;
			} else if (page.getParams().get("fileType").equals(ComConstant.ERROR_MNG) 
					|| page.getParams().get("fileType").equals(ComConstant.BLACK_USE) 
					|| page.getParams().get("fileType").equals(ComConstant.RED_USE) 
					|| page.getParams().get("fileType").equals(ComConstant.INVALID_USE)) {
				List<UploadFileDTO> result = uploadFileDao.selectPage(map);
				int totalCount = uploadFileDao.selectCount(map);
				
				QueryPage<UploadFileDTO> queryPage = new QueryPage<UploadFileDTO>();
				queryPage.setResult(result);
				queryPage.setPageNo(page.getPageNo());
				queryPage.setPageSize(page.getPageSize());
				queryPage.setTotalCount(totalCount);
				return queryPage;
			}
		}
		return null;
	}
	
	@Override
	public UploadFile selectByPrimaryKey(String fileId) {
		return uploadFileDao.selectByPrimaryKey(fileId);
	}
	
	@Override
	public void changeAuditStatus(UploadFile entity) {
		entity.setAuditDate(new Date());
		entity.setAuditStaffId(SysLoginUtil.getLoginUserId());
		this.update(entity);
	}
	
	@Override
	public void changeStatus(String[] fileIds, String status, String fileType) {
		this.updateBatch(fileIds, status);
		if (StringUtils.isNotBlank(fileType)) {
			if (fileType.equals(ComConstant.BLACK_USE)) {
				blackUseService.changeStatusByFileIds(fileIds, status);
			} else if (fileType.equals(ComConstant.INVALID_USE)) {
				invalidUseService.changeStatusByFileIds(fileIds, status);
			} else if (fileType.equals(ComConstant.RED_USE)) {
				redUseService.changeStatusByFileIds(fileIds, status);
			}
		}
	}
	
	@Override
	public void deleteBatch(String fileIds, String fileType) {
		String[] arr = fileIds.split(",");
		List<String> list = new ArrayList<String>();
		for (String fileId : arr) {
			UploadFile uploadFile = this.getById(fileId);
			if (StringUtils.isNotBlank(uploadFile.getAuditStatus()) && uploadFile.getAuditStatus().equals(AUDIT_STATUS_PASS)) {
				continue;
			}
			list.add(fileId);
		}
		if (fileType.equals(ComConstant.BLACK_USE)) {
			blackUseService.delAllByFileIds(list);
		} else if (fileType.equals(ComConstant.RED_USE)) {
			redUseService.delAllByFileIds(list);
		} else if (fileType.equals(ComConstant.INVALID_USE)) {
			invalidUseService.delAllByFileIds(list);
		} else if (fileType.equals(ComConstant.SMS_PHONE)) {
			webSmRecService.delAllByFileIds(list);
		}
		
		
		
		uploadFileDao.deleteBatch(arr);
	}

	@Override
	public List<UploadFileDTO> getRecord(Map<String, Object> params) {
		List<UploadFileDTO> list = uploadFileDao.getRecord(params);
		return list;
	}
	
	@Override
	public void saveUploadData(UploadFile uploadFile, List<List<String>> dataList, Map<String, Object> map) {
		// 设置待审核状态
		if (uploadFile.getFileType().equals(ComConstant.ERROR_MNG) || uploadFile.getFileType().equals(ComConstant.SMS_PHONE)) {
			uploadFile.setAuditStatus(AUDIT_STATUS_UN);
			uploadFile.setStatus(STATUS_INVALID);
		}
		this.save(uploadFile);
		
		this.saveData(uploadFile, dataList, map);
	}
	
	/**
	 * 根据类型保存数据到相应的表
	 * @param uploadFile 文件信息
	 * @param dataList 数据列表
	 * @param listSave 明细列表
	 * @return Integer 成功行数
	 */
	private Integer saveData(UploadFile uploadFile, List<List<String>> dataList, List<InputLine> listSave, Map<String, Object> map) {
		int n = 0;
		// 错误码
		if (uploadFile.getFileType().equals(ComConstant.ERROR_MNG)) {
			n = this.saveErrorMng(uploadFile, dataList, listSave);
			
		} else if (uploadFile.getFileType().equals(ComConstant.BLACK_USE)) { // 黑名单
			n = this.saveBlackUse(uploadFile, dataList, listSave);
			
		} else if (uploadFile.getFileType().equals(ComConstant.RED_USE)) {	//红名单
			n = this.saveRedUse(uploadFile, dataList, listSave);
			
		} else if (uploadFile.getFileType().equals(ComConstant.INVALID_USE)) { // 无效用户
			n = this.saveInvalidUse(uploadFile, dataList, listSave);
			
		} else if (uploadFile.getFileType().equals(ComConstant.SMS_PHONE)) { // 短信号码
			n = this.saveWebSmRec(uploadFile, dataList, listSave, map);
		}
		return n;
	}
	
	/**
	 * 保存错误码信息
	 * @param uploadFile 文件信息
	 * @param dataList 数据列表
	 * @param listSave 明细列表
	 * @return Integer 成功行数
	 */
	private Integer saveErrorMng(UploadFile uploadFile, List<List<String>> dataList, List<InputLine> listSave) {
		// 设置错误码信息并批量保存
		List<ErrorMng> list = new ArrayList<ErrorMng>();
		for (List<String> rowData : dataList) {
			if (rowData.size() < NUMBER_5) {
				continue;
			}
			ErrorMng errorMng = new ErrorMng();
			errorMng.setFileId(uploadFile.getFileId());
			errorMng.setFromType(rowData.get(0));
			errorMng.setErrType(rowData.get(1));
			errorMng.setErrCode(rowData.get(2));
			errorMng.setInnerCode(Integer.parseInt(rowData.get(3)));
			errorMng.setErrMsg(rowData.get(4));
			list.add(errorMng);
		}
		int n = errorMngService.saveBatch(list);
		
		// 更新文件明细导入记录行状态
		List<InputLine> listUpdate = new ArrayList<InputLine>();
		for (int i = 0; i < list.size(); i++) {
			if (StringUtils.isNotBlank(list.get(i).getRecId())) {
				listSave.get(i).setStatus(STATUS_SUCCESS);
			} else {
				listSave.get(i).setStatus(STATUS_FAIL);
				listSave.get(i).setFailReasone(INPUT_ERROR);
			}
			listUpdate.add(listSave.get(i));
		}
		inputLineService.updateBatch(listUpdate);
		return n;
	}
	
	/**
	 * 保存黑名单信息
	 * @param uploadFile 文件信息
	 * @param dataList 数据列表
	 * @param listSave 明细列表
	 * @return Integer 成功行数
	 */
	private Integer saveBlackUse(UploadFile uploadFile, List<List<String>> dataList, List<InputLine> listSave) {
		// 设置黑名单信息并批量保存
		List<BlackUse> list = new ArrayList<BlackUse>();
		for (List<String> rowData : dataList) {
			if (rowData.size() < NUMBER_2) {
				continue;
			}
			BlackUse blackUse = new BlackUse();
			blackUse.setFileId(uploadFile.getFileId());
			blackUse.setBlackUser(rowData.get(0));
			blackUse.setDesc(rowData.get(1));
			list.add(blackUse);
		}
		int n = blackUseService.saveBatch(list);
		
		// 更新文件明细导入记录行状态
		List<InputLine> listUpdate = new ArrayList<InputLine>();
		for (int i = 0; i < list.size(); i++) {
			if (StringUtils.isNotBlank(list.get(i).getRecId())) {
				listSave.get(i).setStatus(STATUS_SUCCESS);
			} else {
				listSave.get(i).setStatus(STATUS_FAIL);
				listSave.get(i).setFailReasone(INPUT_ERROR);
			}
			listUpdate.add(listSave.get(i));
		}
		inputLineService.updateBatch(listUpdate);
		return n;
	}
	
	/**
	 * 保存红名单信息
	 * @param uploadFile 文件信息
	 * @param dataList 数据列表
	 * @param listSave 明细列表
	 * @return Integer 成功行数
	 */
	private Integer saveRedUse(UploadFile uploadFile, List<List<String>> dataList, List<InputLine> listSave) {
		// 设置红名单信息并批量保存
		List<RedUserList> list = new ArrayList<RedUserList>();
		for (List<String> rowData : dataList) {
			if (rowData.size() < NUMBER_2) {
				continue;
			}
			List<RedUserList> haveList = redUseService.selectByphone(rowData.get(0));
			if (haveList.size() > 0) {
				haveList.get(0).setRemark(rowData.get(1));
				haveList.get(0).setStatus("1");
				redUseService.update(haveList.get(0));
				continue;
			}
			RedUserList redUse = new RedUserList();
			redUse.setPhone(rowData.get(0));
			redUse.setRemark(rowData.get(1));
			redUse.setFileId(uploadFile.getFileId());
			redUse.setStatus("1");	//默认有效
			list.add(redUse);
		}
		int n = redUseService.saveBatch(list);
		
		// 更新文件明细导入记录行状态
		List<InputLine> listUpdate = new ArrayList<InputLine>();
		for (int i = 0; i < list.size(); i++) {
			if (StringUtils.isNotBlank(list.get(i).getRecId())) {
				listSave.get(i).setStatus(STATUS_SUCCESS);
			} else {
				listSave.get(i).setStatus(STATUS_FAIL);
				listSave.get(i).setFailReasone(INPUT_ERROR);
			}
			listUpdate.add(listSave.get(i));
		}
		inputLineService.updateBatch(listUpdate);
		return n;
	}
	
	/**
	 * 保存无效用户信息
	 * @param uploadFile 文件信息
	 * @param dataList 数据列表
	 * @param listSave 明细列表
	 * @return Integer 成功行数
	 */
	private Integer saveInvalidUse(UploadFile uploadFile, List<List<String>> dataList, List<InputLine> listSave) {
		// 设置无效用户信息并批量保存
		List<InvalidUse> list = new ArrayList<InvalidUse>();
		for (List<String> rowData : dataList) {
			if (rowData.size() < NUMBER_2) {
				continue;
			}
			InvalidUse invalidUse = new InvalidUse();
			invalidUse.setFrom(uploadFile.getFileId());
			invalidUse.setInvalidUser(rowData.get(0));
			invalidUse.setDesc(rowData.get(1));
			list.add(invalidUse);
		}
		int n = invalidUseService.saveBatch(list);
		
		// 更新文件明细导入记录行状态
		List<InputLine> listUpdate = new ArrayList<InputLine>();
		for (int i = 0; i < list.size(); i++) {
			if (StringUtils.isNotBlank(list.get(i).getRecId())) {
				listSave.get(i).setStatus(STATUS_SUCCESS);
			} else {
				listSave.get(i).setStatus(STATUS_FAIL);
				listSave.get(i).setFailReasone(INPUT_ERROR);
			}
			listUpdate.add(listSave.get(i));
		}
		inputLineService.updateBatch(listUpdate);
		return n;
	}
	
	/**
	 * 保存门户短信文件导入信息
	 * @param uploadFile 文件信息
	 * @param dataList 数据列表
	 * @param listSave 明细列表
	 * @return Integer 成功行数
	 */
	@SuppressWarnings("unchecked")
	private Integer saveWebSmRec(UploadFile uploadFile, List<List<String>> dataList, List<InputLine> listSave, Map<String, Object> map) {
		Map<String, Object> params = (Map<String, Object>)map.get("smsPhone");
		String sendMode = params.get("sendMode").toString();
		
		// 设置短信信息并批量保存
		List<WebSmRec> list = new ArrayList<WebSmRec>();
		int l = 0;
		for (List<String> rowData : dataList) {
			++l;
			if ((sendMode.equals(WebSmRec.SEND_MODE_MASS_PHONE) && rowData.size() < NUMBER_1) 
					|| (sendMode.equals(WebSmRec.SEND_MODE_MASS_SMS) && rowData.size() < NUMBER_2)) {
				continue;
			}
			StringBuilder lineContent = new StringBuilder();
			for (String string : rowData) {
				lineContent.append(string);
			}
			WebSmRec webSmRec = new WebSmRec();
			webSmRec.setFileLineSeq(l);
			webSmRec.setSvrNode((String)params.get("svrNode"));
			webSmRec.setServiceCode((String)params.get("serviceCode"));
			webSmRec.setSendPort((String)params.get("sendPort"));
			webSmRec.setSendMode(sendMode);
			webSmRec.setFileId(uploadFile.getFileId());
			webSmRec.setRemark((String)params.get("remark"));
			webSmRec.setLineContent(lineContent.toString());
			if (sendMode.equals(WebSmRec.SEND_MODE_MASS_PHONE)) {
				webSmRec.setPhone(rowData.get(0));
				webSmRec.setSmContent((String)params.get("smContent"));
			} else if (sendMode.equals(WebSmRec.SEND_MODE_MASS_SMS)) {
				webSmRec.setPhone(rowData.get(0));
				webSmRec.setSmContent(rowData.get(1));
			}
			list.add(webSmRec);
		}
		int n = webSmRecService.saveBatch(list);
		
		// 更新文件明细导入记录行状态
//		List<InputLine> listUpdate = new ArrayList<InputLine>();
//		for (int i = 0; i < list.size(); i++) {
//			if (StringUtils.isNotBlank(list.get(i).getSmSeq())) {
//				listSave.get(i).setStatus(STATUS_SUCCESS);
//			} else {
//				listSave.get(i).setStatus(STATUS_FAIL);
//				listSave.get(i).setFailReasone(INPUT_ERROR);
//			}
//			listUpdate.add(listSave.get(i));
//		}
//		inputLineService.updateBatch(listUpdate);
		return n;
	}
	
	/**
	 * 保存
	 * @param entity UploadFile
	 */
	private void save(UploadFile entity) {
		entity.setUserId(SysLoginUtil.getLoginUserId());
		entity.setUptime(new Date());
		entity.setInsertTime(new Date());
		entity.setInsertStaffId(SysLoginUtil.getLoginUserId());
		entity.setLastModTime(entity.getInsertTime());
		entity.setLastModStaffId(entity.getInsertStaffId());
		uploadFileDao.insertSelective(entity);
	}
	
	/**
	 * 更新
	 * @param entity UploadFile
	 */
	private void update(UploadFile entity) {
		uploadFileDao.updateByPrimaryKey(entity);
	}
	
	/**
	 * 批量更新
	 * @param fileIds 多个文件ID
	 * @param status 状态
	 */
	private void updateBatch(String[] fileIds, String status) {
		if (fileIds.length > 0) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("array", fileIds);
			map.put("status", status);
			uploadFileDao.changeStatus(map);
		}
	}
	
	/**
	 * 获取发送方式
	 * @param uploadFile 上传文件
	 * @param map 短信电话文件参数
	 * @return sendMode
	 */
	@SuppressWarnings("unchecked")
	private String getSendMode(UploadFile uploadFile, Map<String, Object> map) {
		String sendMode = "";
		if (uploadFile.getFileType().equals(ComConstant.SMS_PHONE)) {
			Map<String, Object> params = (Map<String, Object>)map.get("smsPhone");
			sendMode = params.get("sendMode").toString();
		}
		return sendMode;
	}

	@Override
	public UploadWebSmDTO toUpdate(String fileId) {
		return webSmRecService.toUpdate(fileId);
	}

	@Override
	public void update(UploadFile uploadFile, List<List<String>> dataList, Map<String, Object> map) {
		Map<String, Object> params = new HashMap<>();
		params.put("fileId", uploadFile.getFileId());
		webSmRecService.delAllByFileId(uploadFile.getFileId());
		inputLineService.delete(params);
		this.update(uploadFile);
		this.saveData(uploadFile, dataList, map);
	}

	@Override
	public UploadFile getById(String fileId) {
		return uploadFileDao.selectByPrimaryKey(fileId);
	}
	
	/**
	 * 保存上传文件数据
	 * @param uploadFile 文件信息
	 * @param dataList 数据列表
	 * @param map 参数
	 */
	private void saveData(UploadFile uploadFile, List<List<String>> dataList, Map<String, Object> map) {
		String sendMode = this.getSendMode(uploadFile, map);
		
		// 保存文件明细
		List<InputLine> listSave = new ArrayList<InputLine>();
		for (int i = 0; i < dataList.size(); i++) {
			InputLine inputLine = new InputLine();
			inputLine.setFileId(uploadFile.getFileId());
			inputLine.setLineNo(i + 1);
			inputLine.setLineContent(StringUtils.join(dataList.get(i), "|"));
			// 判断内容格式是否正确
			if ((uploadFile.getFileType().equals(ComConstant.ERROR_MNG) && dataList.get(i).size() < NUMBER_5) 
					|| (uploadFile.getFileType().equals(ComConstant.BLACK_USE) && dataList.get(i).size() < NUMBER_2) 
					|| (uploadFile.getFileType().equals(ComConstant.RED_USE) && dataList.get(i).size() < NUMBER_2)
					|| (uploadFile.getFileType().equals(ComConstant.INVALID_USE) && dataList.get(i).size() < NUMBER_2)
					|| (uploadFile.getFileType().equals(ComConstant.SMS_PHONE) && sendMode.equals(WebSmRec.SEND_MODE_MASS_PHONE)
							&& dataList.get(i).size() < NUMBER_1)
					|| (uploadFile.getFileType().equals(ComConstant.SMS_PHONE) && sendMode.equals(WebSmRec.SEND_MODE_MASS_SMS)
							&& dataList.get(i).size() < NUMBER_2)) {
				inputLine.setStatus(STATUS_FAIL);
				inputLine.setFailReasone(FORMAT_ERROR);
			} else {
				inputLine.setStatus(STATUS_SUCCESS);
			}
			listSave.add(inputLine);
		}
		inputLineService.saveBatch(listSave);
		// 移除格式错误的记录
		Iterator<InputLine> iterator = listSave.iterator(); 
		while (iterator.hasNext()) {
			InputLine inputLine = iterator.next();
			if (StringUtils.isNotBlank(inputLine.getStatus()) && inputLine.getStatus().equals(STATUS_FAIL)) {
				iterator.remove();
			}
		}
		
		this.saveData(uploadFile, dataList, listSave, map);
		
		// 保存导入成功与失败行数
		uploadFile.setOkLines(listSave.size());
		uploadFile.setFailLines(dataList.size() - listSave.size());
		this.update(uploadFile);
	}

	@Override
	public List<UploadWebSmDTO> getRecordWebSmRec(Map<String, Object> params) {
		List<UploadWebSmDTO> list = null;
		params.put("userId", SysLoginUtil.getLoginUserId());
		if (roleService.isRootAcsFlag(SysLoginUtil.getLoginUserId())) {
			list = webSmRecService.getRecordRoot(params);
		} else {
			list = webSmRecService.getRecordUnit(params);
		}
		return list;
	}

}
